/*********************************************************
/*     Copyright (c) 2020 上海芯翌智能科技有限公司     
/*       公司内部代码, 未经允许, 不得使用和传播.       
**********************************************************/

#ifndef __XFFWCC_LOG_LOG_STREAM__
#define __XFFWCC_LOG_LOG_STREAM__

#include <string.h>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
namespace xffwcc {
namespace log {

class LogStream {
 public:
  LogStream() {}

  ~LogStream() {}

  typedef LogStream self;

 public:
  self &operator<<(bool v) {
    stream_ << (v ? "1" : "0");
    return *this;
  }

  self &operator<<(short v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(unsigned short v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(int v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(unsigned int v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(long v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(unsigned long v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(long long v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(unsigned long long v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(double v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(float v) {
    *this << static_cast<double>(v);
    return *this;
  }

  self &operator<<(char v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(signed char v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(unsigned char v) {
    stream_ << v;
    return *this;
  }

  self &operator<<(const char *str) {
    if (str) {
      stream_ << str;
    } else {
      stream_ << "(null)";
    }
    return *this;
  }

  self &operator<<(const unsigned char *str) {
    return operator<<(reinterpret_cast<const char *>(str));
  }

  self &operator<<(const std::string &v) {
    stream_ << v;
    return *this;
  }

  const std::stringstream &GetStream() const { return stream_; }

  const std::string ToString() { return stream_.str(); }

  void clearStream() { stream_.clear(); }

 private:
  void staticCheck() {
    static_assert(kMaxNumericSize - 10 > std::numeric_limits<double>::digits10,
                  "kMaxNumericSize is large enough");
    static_assert(
        kMaxNumericSize - 10 > std::numeric_limits<long double>::digits10,
        "kMaxNumericSize is large enough");
    static_assert(kMaxNumericSize - 10 > std::numeric_limits<long>::digits10,
                  "kMaxNumericSize is large enough");
    static_assert(
        kMaxNumericSize - 10 > std::numeric_limits<long long>::digits10,
        "kMaxNumericSize is large enough");
  }

  std::stringstream stream_;
  static const int kMaxNumericSize = 32;
};
}  // namespace log
}  // namespace xffwcc
#endif  //__LOG_STREAM__
